package com.xin.di.uav.applet.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xin.di.uav.applet.config.DelayQueue;
import com.xin.di.uav.applet.po.Dictionary;
import com.xin.di.uav.applet.resp.*;
import com.xin.di.uav.applet.service.OrderService;
import com.xin.di.uav.applet.service.WechatPayService;
import com.xin.di.uav.common.request.CarrierWaybillRequest;
import com.xin.di.uav.common.request.CreateWaybillRequest;
import com.xin.di.uav.common.utils.FyUtils;
import com.xin.di.uav.common.utils.PhoneEncoderUtil;
import com.xin.di.uav.mapper.BillMapper;
import com.xin.di.uav.mapper.OrderCommodityMapper;
import com.xin.di.uav.mapper.ScenicSpotMapper;
import com.xin.di.uav.mapper.SpecificationDao;
import com.xin.di.uav.operate.mapper.CustomDeliveryPointMapper;
import com.xin.di.uav.operate.mapper.PlacementPointMapper;
import com.xin.di.uav.operate.po.DeliveryPointPO;
import com.xin.di.uav.operate.service.LoginService;
import com.xin.di.uav.applet.mapper.*;
import com.xin.di.uav.applet.rest.*;
import com.xin.di.uav.applet.service.IOrderInfoService;
import com.xin.di.uav.common.awt.JwtUtil;
import com.xin.di.uav.common.enums.*;
import com.xin.di.uav.common.exception.BusinessException;
import com.xin.di.uav.common.request.order.BillAddRequest;
import com.xin.di.uav.common.request.order.CheckOrderRequest;
import com.xin.di.uav.common.request.order.CommodityRequest;
import com.xin.di.uav.common.request.order.RescuePrepareOrderRequest;
import com.xin.di.uav.common.request.order.task.ConfirmPayRequest;
import com.xin.di.uav.common.utils.BeanUtil;
import com.xin.di.uav.common.utils.RedisPrefixKey;
import com.xin.di.uav.operate.po.PlacementPoint;
import com.xin.di.uav.operate.rest.PlacementPointRest;
import com.xin.di.uav.po.*;
import com.xin.di.uav.user.entity.UserExtra;
import com.xin.di.uav.user.mapper.UserExtraMapper;
import com.xin.di.uav.user.order.po.OrderPO;
import com.xin.di.uav.user.order.po.Product;
import com.xin.di.uav.user.order.po.TaskStatusLog;
import com.xin.di.uav.user.order.service.CommonOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author LTQ
 */
@Service
public class OrderServiceImpl implements OrderService {
    private final static Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
    @Autowired
    private PlacementPointMapper placementPointMapper;

    @Autowired
    private ScenicSpotMapper scenicSpotMapper;
    @Autowired
    private IOrderInfoService iOrderInfoService;

    @Autowired
    private DictionaryRest dictionaryRest;


    @Autowired
    private OrderMapper orderInfoMapper;
    @Autowired
    private CustomDeliveryPointMapper customDeliveryPointMapper;

    @Autowired
    private WechatPayService wechatPayService;

    @Autowired
    private ScenicSpotRest scenicSpotRest;


    @Autowired
    private TaskStatusLogRest taskStatusLogRest;

    @Autowired
    private CommonOrderService commonOrderService;


    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private FyUtils fyUtils;

    @Autowired
    private DelayQueue delayQueue;

    @Autowired
    private BillRest billRest;


    @Autowired
    private LoginService loginService;

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private UserExtraMapper userExtraMapper;

    @Autowired
    private PlacementPointRest placementPointRest;

    @Autowired
    private OrderCommodityMapper orderCommodityMapper;

    @Autowired
    private OrderCommodityRest orderCommodityRest;

    @Autowired
    private OrderInfoRest orderInfoRest;
    @Autowired
    private BillMapper billMapper;
    @Autowired
    private SpecificationDao specificationDao;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Date expireOrder(String id) {
        OrderPO orderInfo = orderInfoMapper.selectById(id);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new BusinessException("订单不存在");
        } else {
            if (orderInfo.getStatus().equals(RescueOrderStatusEnum.TO_BE_PAID.getStatus())) {
                orderInfo.setStatus(RescueOrderStatusEnum.EXPIRE.getStatus());
                Date date = new Date();
                orderInfo.setUpdatedAt(date);
                orderInfoMapper.updateById(orderInfo);
                TaskStatusLog taskStatusLog = new TaskStatusLog();
                taskStatusLog.setStatus(RescueOrderStatusEnum.EXPIRE.getStatus());
                taskStatusLog.setTaskId(orderInfo.getId());
                taskStatusLog.setCreateTime(date);
                taskStatusLog.setUpdateTime(date);
                taskStatusLog.setUserId(orderInfo.getUserId());
                taskStatusLogRest.add(taskStatusLog);
                //恢复库存
                commonOrderService.restoreInventory(orderInfo.getOrderNo());
                return orderInfo.getUpdatedAt();
            }
        }
        return null;
    }


    @Override
    @Transactional
    public Map<String, String> placeOrder(RescuePrepareOrderRequest rescuePrepareOrderRequest) {
        //也可以指定锁时间的
        String userId = JwtUtil.getUserId();
        List<CommodityRequest> commodityRequests = rescuePrepareOrderRequest.getCommodityRequests();


        BigDecimal totalPrice = rescuePrepareOrderRequest.getTotalPrice();
        String placementPointId = rescuePrepareOrderRequest.getPlacementPointId();
        //1校验投放点
        PlacementPoint placementPoint = placementPointRest.selectById(placementPointId);
        if (ObjectUtils.isEmpty(placementPoint)) {
            throw new BusinessException("投放点已关闭，请联系客服");
        }
        //校验景区
        String scenicSpotId = placementPoint.getScenicSpotId();
        ScenicSpot scenicSpot = scenicSpotRest.selectById(scenicSpotId);
        if (ObjectUtils.isEmpty(scenicSpot)) {
            throw new BusinessException("景区已关闭，请联系客服");
        }
        BigDecimal originalExpressFee = placementPoint.getExpressFee();
        List<SpecificationPO> specificationPOS = new ArrayList<>();
        List<String> speIds = commodityRequests.stream().map(CommodityRequest::getSpeId).filter(specificationId -> !ObjectUtils.isEmpty(specificationId)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(speIds)) {
            specificationPOS = specificationDao.selByIds(speIds);
        }
        List<Product> commodities = this.checkOrderData(rescuePrepareOrderRequest, originalExpressFee, specificationPOS);
        rescuePrepareOrderRequest.setPrice(rescuePrepareOrderRequest.getPrice().setScale(2, RoundingMode.HALF_UP));
        rescuePrepareOrderRequest.setExpressFee(rescuePrepareOrderRequest.getExpressFee().setScale(2, RoundingMode.HALF_UP));
        BigDecimal price = rescuePrepareOrderRequest.getPrice();
        BigDecimal expressFee = rescuePrepareOrderRequest.getExpressFee();
        BigDecimal pricePayable = price.add(expressFee);
        if (pricePayable.compareTo(totalPrice) != 0) {
            throw new BusinessException("总价异常，请联系客服");
        }

        Date date = new Date();

        OrderPO orderInfo = BeanUtil.copyProperties(rescuePrepareOrderRequest, OrderPO.class);
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
        String dateString = sdf.format(new Date());
        String orderSn = "SN" + dateString + UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6);

        orderInfo.setPayPhone(rescuePrepareOrderRequest.getReceiverTel());
        orderInfo.setReceiveName(rescuePrepareOrderRequest.getReceiverName());
        orderInfo.setStatus(RescueOrderStatusEnum.TO_BE_PAID.getStatus());
        orderInfo.setUserId(userId);
        orderInfo.setPlacementPointId(placementPointId);
        orderInfo.setOrderNo(orderSn);
        orderInfo.setExpressFee(originalExpressFee);
        orderInfo.setTotalAmount(pricePayable);
        orderInfo.setPricePayable(pricePayable);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, 10);
        orderInfo.setExpireTime(c.getTime());
        orderInfo.setPlatformCode(PlatformCodeEnum.SCENIC_SPOT_EXPRESS.getCode());
        iOrderInfoService.insert(orderInfo);

        //进行商品记录
        for (CommodityRequest commodityRequest : commodityRequests) {
            Integer cnt = commodityRequest.getCnt();
            String id = commodityRequest.getId();
            OrderCommodity orderCommodity = new OrderCommodity();
            orderCommodity.setOrderSn(orderInfo.getOrderNo());
            orderCommodity.setSpeId(commodityRequest.getSpeId());
            orderCommodity.setCommodityId(id);
            orderCommodity.setCreateTime(date);
            orderCommodity.setUpdateTime(date);
            orderCommodity.setValue(commodityRequest.getValue());
            orderCommodity.setValue2(commodityRequest.getValue2());
            orderCommodity.setValue3(commodityRequest.getValue3());
            orderCommodity.setValue4(commodityRequest.getValue4());
            orderCommodity.setValue5(commodityRequest.getValue5());
            for (Product commodity : commodities) {
                if (commodity.getId().equals(id)) {
                    orderCommodity.setName(commodity.getName());
                    orderCommodity.setImages(commodity.getMainImage());
//                    orderCommodity.setIntroduction(commodity.getIntroduction());
                    String speId = commodityRequest.getSpeId();
                    if (!commodity.isStatus()) {
                        throw new BusinessException("商品：" + commodity.getName() + "已下架");
                    }
                    if (ObjectUtils.isEmpty(speId)) {
                        orderCommodity.setPrice(commodity.getSalePrice());
                        Integer amount = commodity.getStock();
                        if (cnt > amount) {
                            throw new BusinessException("商品：" + commodity.getName() + "的库存不足仅剩" + commodity.getStock());
                            //库存不足
//                        JSONObject jsonObject = new JSONObject();
//                        jsonObject.put("commodityId", commodity.getId());
//                        jsonObject.put("businessId", commodity.getMerchantId());
//                        jsonObject.put("commodityName", commodity.getName());
//                        jsonObject.put("amount", amount);
//                        jsonObject.put("errorMsg", ErrorEnum.COMMODITY_LIMIT.getErrMsg());
//                        errorObjects.add(jsonObject);
                        } else {
                            commodity.setStock(amount - cnt);
                            commodityMapper.updateStock(commodity);
                        }
                    } else {
                        for (SpecificationPO specificationPO : specificationPOS) {
                            if (speId.equals(specificationPO.getId())) {
                                orderCommodity.setPrice(specificationPO.getSalePrice());
                                Integer amount = specificationPO.getStock();
                                if (cnt > amount) {
                                    throw new BusinessException("商品：" + commodity.getName() + "的库存不足仅剩" + commodity.getStock());
                                } else {
                                    specificationPO.setStock(amount - cnt);
                                    specificationDao.updateStock(specificationPO);
                                }
                            }
                        }
                    }


                    orderCommodity.setCnt(cnt);
                    orderCommodityMapper.insert(orderCommodity);
                }
            }
        }
//        if (errorObjects.size() > 0) {
//            throw new BusinessException(ErrorEnum.COMMODITY_LIST_UN_NORMAL, errorObjects.toString());
//        }
        Map<String, String> payImgInfo = wechatPayService.wechatPay(pricePayable, orderSn, null, "外卖下单", rescuePrepareOrderRequest.getLoginCode());
        this.dealAfterPlaceOrder(orderInfo);
        payImgInfo.put("orderSn", orderSn);
        redisTemplate.opsForValue().set(ServicePrefixEnum.RESCUE + RedisPrefixKey.PAY_SETTING + orderInfo.getId(), payImgInfo);
        redisTemplate.expire(ServicePrefixEnum.RESCUE + RedisPrefixKey.PAY_SETTING + orderInfo.getId(), 10, TimeUnit.MINUTES);
        //支付
        delayQueue.pushQueue(ServicePrefixEnum.RESCUE + RedisPrefixKey.ORDER_COUNT_DOWN + orderInfo.getId(), c.getTime().getTime() - date.getTime());


        BillAddRequest billAddRequest = new BillAddRequest();
        billAddRequest.setOrderId(orderInfo.getId());
        billAddRequest.setTcWaybillNo(orderInfo.getOrderNo());
        billAddRequest.setPricePaid(orderInfo.getTotalAmount());
        billAddRequest.setPayStatus(PayStatusEnum.PENDING.getValue());
        billAddRequest.setUserId(orderInfo.getUserId());
        billAddRequest.setType(OrderTypeEnum.INCOME.getValue());
        billRest.add(billAddRequest);
        return payImgInfo;

    }

    @Override
    public String getNewOpenId(String loginCode) {
        Object object;
        object = redisTemplate.opsForValue().get(ServicePrefixEnum.RESCUE + RedisPrefixKey.WX_LOGIN_DATA + loginCode);
        if (ObjectUtils.isEmpty(object)) {
            object = loginService.decipheringCode(loginCode);
        }
        return (String) ((JSONObject) object).get("openid");
    }

    @Async
    public void dealAfterPlaceOrder(OrderPO orderInfo) {
        Date date = orderInfo.getCreatedAt();
        TaskStatusLog taskStatusLog = new TaskStatusLog();
        taskStatusLog.setStatus(orderInfo.getStatus());
        taskStatusLog.setTaskId(orderInfo.getId());
        taskStatusLog.setCreateTime(date);
        taskStatusLog.setUpdateTime(date);
        taskStatusLog.setUserId(orderInfo.getUserId());
        taskStatusLogRest.add(taskStatusLog);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Object confirmPay(ConfirmPayRequest confirmPayRequest) {
        logger.info("confirmPayRequest" + confirmPayRequest.toString());
        Date date = new Date();
        OrderPO orderInfo = orderInfoMapper.selByOrderSn(confirmPayRequest.getTradeNo());
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new BusinessException("交易号不存在，请联系客服");
        }
        if (RescueOrderStatusEnum.TO_BE_PAID.getStatus().equals(orderInfo.getStatus())) {
            orderInfo.setStatus(RescueOrderStatusEnum.WAITING_FOR_ORDER_ACCEPTANCE.getStatus());
            orderInfo.setUpdatedAt(date);

            orderInfo.setOrderNo(confirmPayRequest.getTradeNo());
            orderInfo.setTransactionId(confirmPayRequest.getTransactionId());
            String placementPointId = orderInfo.getPlacementPointId();
            PlacementPoint placementPoint = placementPointRest.selectById(placementPointId);
            if (placementPoint != null) {
                Integer expressDuration = placementPoint.getExpressDuration();
                if (expressDuration != null) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(date);
                    calendar.add(Calendar.MINUTE, expressDuration);
                    Date newDate = calendar.getTime();
                    orderInfo.setEstimatedDeliveryTime(newDate);
                }

            }


            orderInfo.setConfirmPayTime(date);
            String fyCode = this.sendOrder(orderInfo);
            orderInfo.setFyOrderNo(fyCode);
            orderInfoMapper.updateById(orderInfo);
            //记录任务日志
            TaskStatusLog taskStatusLog = new TaskStatusLog();
            taskStatusLog.setStatus(RescueOrderStatusEnum.WAITING_FOR_ORDER_ACCEPTANCE.getStatus());
            taskStatusLog.setTaskId(orderInfo.getId());
            taskStatusLog.setCreateTime(date);
            taskStatusLog.setUpdateTime(date);
            taskStatusLog.setUserId(orderInfo.getUserId());
            taskStatusLogRest.add(taskStatusLog);
            delayQueue.pushQueue(ServicePrefixEnum.RESCUE + RedisPrefixKey.SEND_NOTICE + orderInfo.getId(), 0L);

            delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.SOCKET_TOKEN + orderInfo.getId(), 0L);

            logger.info("下单成功");
        }
        return null;
    }
    public String sendOrder(OrderPO orderPO) {
        String placementPointId = orderPO.getPlacementPointId();
        PlacementPoint placementPoint = placementPointMapper.selectById(placementPointId);
        if (placementPoint == null) {
            throw new BusinessException("投放点不存在");
        }
        String scenicSpotId = placementPoint.getScenicSpotId();
        ScenicSpot scenicSpot = scenicSpotMapper.selectById(scenicSpotId);
        if (scenicSpot == null) {
            throw new BusinessException("服务区不存在");
        }
        CarrierWaybillRequest carrierWaybillRequest = new CarrierWaybillRequest();
        carrierWaybillRequest.setGpsType(1);
        carrierWaybillRequest.setGoodsType(1);
        carrierWaybillRequest.setGoodsWeight(10);
        carrierWaybillRequest.setReceiverLat(placementPoint.getLatitude().toString());
        carrierWaybillRequest.setReceiverLon(placementPoint.getLongitude().toString());
        carrierWaybillRequest.setSenderLon(placementPoint.getSenderLongitude().toString());
        carrierWaybillRequest.setSenderLat(placementPoint.getSenderLatitude().toString());
        JSONObject jsonObject1 = fyUtils.carrierWaybill(carrierWaybillRequest);
        System.out.println(jsonObject1);
        CreateWaybillRequest createWaybillRequest = new CreateWaybillRequest();
        String takeoffCode = jsonObject1.getJSONObject("obj").getString("takeoffCode");
        String landingCode = jsonObject1.getJSONObject("obj").getString("landingCode");
        createWaybillRequest.setSenderCode(takeoffCode);
        createWaybillRequest.setReceiverCode(landingCode);


        createWaybillRequest.setSenderTel(placementPoint.getSenderTel());
        createWaybillRequest.setSenderAddr(placementPoint.getSenderAddr());
        createWaybillRequest.setSenderName(placementPoint.getSenderName());


        createWaybillRequest.setAmount(orderPO.getTotalAmount().doubleValue());
        createWaybillRequest.setPushTime(String.valueOf(System.currentTimeMillis()));
        createWaybillRequest.setReceiverTel(orderPO.getPayPhone());
        createWaybillRequest.setReceiverName(orderPO.getReceiveName());
        createWaybillRequest.setReceiverAddr(scenicSpot.getAddress());

        return fyUtils.createWaybill(createWaybillRequest);
    }

    @Override
    public void sendPaySuccessMsg(String orderId) {

        OrderPO orderInfo = orderInfoMapper.selectById(orderId);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单记录为空");
        }
        Date updateTime = orderInfo.getUpdatedAt();

        Bill bill = billMapper.selectIncomePending(orderInfo.getOrderNo());
        if (!ObjectUtils.isEmpty(bill)) {
            bill.setUpdateTime(updateTime);
            bill.setOtherOrderNo(orderInfo.getTransactionId());
            bill.setPricePaid(orderInfo.getTotalAmount());
            bill.setPayStatus(PayStatusEnum.SUCCESS.getValue());
            billMapper.updateStatus(bill);
        }


    }

    @Override
    public OrderListResponse getOrderList(Integer page, Integer size) {
        OrderListResponse orderListResponse = new OrderListResponse();
        size = size + 1;
        List<OrderPO> orderInfoList = orderInfoRest.getOrders(page, size);
        if (orderInfoList.size() == size) {
            orderListResponse.setHasNext(true);
            orderInfoList.remove(size - 1);
        }
        List<RescueOrderResponse> rescueOrderResponses = new ArrayList<>();
        //还要记录商品列表，总购买数量
        if (!CollectionUtils.isEmpty(orderInfoList)) {
            List<String> orderSns = orderInfoList.stream().map(OrderPO::getOrderNo).collect(Collectors.toList());
            List<OrderCommodity> orderCommodities = orderCommodityRest.getByOrderSns(orderSns);

            orderInfoList.forEach(orderInfo -> {
                RescueOrderResponse rescueOrderResponse = BeanUtil.copyProperties(orderInfo, RescueOrderResponse.class);
                List<OrderCommodity> orderCommodityList = orderCommodities.stream().filter(orderCommodity -> orderCommodity.getOrderSn().equals(orderInfo.getOrderNo())).collect(Collectors.toList());


                Integer totalCnt = orderCommodityList.stream().map(OrderCommodity::getCnt).reduce(0, Integer::sum);
                rescueOrderResponse.setTotalCnt(totalCnt);


                List<OrderCommodity> orderCommodities1 = orderCommodityList.stream().filter(orderCommodity -> orderCommodity.getOrderSn().equals(orderInfo.getOrderNo())).collect(Collectors.toList());
                List<CommodityResponse> commodityResponses = BeanUtil.copyProperties(orderCommodities1, CommodityResponse.class);
                rescueOrderResponse.setCommodityResponses(commodityResponses);
                rescueOrderResponses.add(rescueOrderResponse);
            });
        }
        orderListResponse.setRescueOrderResponses(rescueOrderResponses);
        return orderListResponse;
    }


    /**
     * 校验快递费和投放点,和商品数量
     *
     * @param rescuePrepareOrderRequest
     */
    private List<Product> checkOrderData(RescuePrepareOrderRequest rescuePrepareOrderRequest, BigDecimal originalExpressFee, List<SpecificationPO> specificationPOS) {
        //校验快递费
        BigDecimal expressFee = rescuePrepareOrderRequest.getExpressFee().setScale(2, RoundingMode.HALF_UP);

        if (expressFee.compareTo(originalExpressFee) != 0) {
            throw new BusinessException("快递费被篡改，请联系客服");
        }
        Integer num = rescuePrepareOrderRequest.getNum();
        if (num < 1) {
            throw new BusinessException("购买商品数量不能为0");
        }
        List<CommodityRequest> commodityRequests = rescuePrepareOrderRequest.getCommodityRequests();
        //购买商品总数量
        Integer totalCnt = commodityRequests.stream().map(CommodityRequest::getCnt).reduce(0, Integer::sum);

        if (!num.equals(totalCnt)) {
            throw new BusinessException("总商品数量被篡改，请联系客服");
        }
        BigDecimal price = rescuePrepareOrderRequest.getPrice().setScale(2, RoundingMode.HALF_UP);

        List<String> ids = commodityRequests.stream().map(CommodityRequest::getId).collect(Collectors.toList());
        List<String> speIds = commodityRequests.stream().map(CommodityRequest::getSpeId).filter(specificationId -> !ObjectUtils.isEmpty(specificationId)).collect(Collectors.toList());

        List<Product> commodities = commodityMapper.selByIds(ids);
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (CommodityRequest commodityRequest : commodityRequests) {
            for (Product commodity : commodities) {

                if (commodityRequest.getId().equals(commodity.getId())) {
                    List<SpecificationPO> specificationPOList = specificationPOS.stream().filter(specificationPO -> specificationPO.getProductId().equals(commodity.getId())).collect(Collectors.toList());
                    if (!CollectionUtil.isEmpty(specificationPOList)) {
                        for (SpecificationPO specificationPO : specificationPOList) {
                            if (commodityRequest.getId().equals(specificationPO.getProductId()) && specificationPO.getId().equals(commodityRequest.getSpeId())) {
                                totalPrice = totalPrice.add(specificationPO.getSalePrice().multiply(new BigDecimal(commodityRequest.getCnt())));
                            }
                        }
                    } else {
                        totalPrice = totalPrice.add(commodity.getSalePrice().multiply(new BigDecimal(commodityRequest.getCnt())));
                    }

                }


            }


        }

        if (totalPrice.setScale(2, RoundingMode.HALF_UP).compareTo(price) != 0) {
            throw new BusinessException("商品价格发生变动，请重新下单");
        }
        return commodities;
    }

    @Override
    public CheckOrderResponse checkOrder(CheckOrderRequest checkOrderRequest) {
        checkOrderRequest.setPrice(checkOrderRequest.getPrice().setScale(2, RoundingMode.HALF_UP));
        String placementPointId = checkOrderRequest.getPlacementPointId();
        List<CommodityRequest> commodityRequests = checkOrderRequest.getCommodityRequests();
        //1校验投放点
        PlacementPoint placementPoint = placementPointRest.selectById(placementPointId);
        if (ObjectUtils.isEmpty(placementPoint)) {
            throw new RuntimeException("投放点已关闭，请联系客服");
        }
        //校验景区
        String scenicSpotId = placementPoint.getScenicSpotId();
        ScenicSpot scenicSpot = scenicSpotRest.selectById(scenicSpotId);
        if (ObjectUtils.isEmpty(scenicSpot)) {
            throw new RuntimeException("景区已关闭，请联系客服");
        }
        BigDecimal originalExpressFee = placementPoint.getExpressFee();
        RescuePrepareOrderRequest rescuePrepareOrderRequest = BeanUtil.copyProperties(checkOrderRequest, RescuePrepareOrderRequest.class);
        rescuePrepareOrderRequest.setExpressFee(new BigDecimal(checkOrderRequest.getExpressFee()));
        List<SpecificationPO> specificationPOS = new ArrayList<>();
        List<String> speIds = commodityRequests.stream().map(CommodityRequest::getSpeId).filter(specificationId -> !ObjectUtils.isEmpty(specificationId)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(speIds)) {
            specificationPOS = specificationDao.selByIds(speIds);
        }
        List<Product> commodities = this.checkOrderData(rescuePrepareOrderRequest, originalExpressFee, specificationPOS);
        CheckOrderResponse checkOrderResponse = BeanUtil.copyProperties(checkOrderRequest, CheckOrderResponse.class);
        checkOrderResponse.setPlacementPointName(placementPoint.getName());
        checkOrderResponse.setDeliveryMethod(DeliveryMethodEnum.UAV.getValue());
        Dictionary dictionary = dictionaryRest.getBySubject(DictionarySubjectEnum.DELIVERY_TIME.getCode());
        if (!ObjectUtils.isEmpty(dictionary)) {
            checkOrderResponse.setDeliveryTime(dictionary.getDecimalValue());
        }
        List<CommodityResponse> commodityResponses = new ArrayList<>();
        final BigDecimal[] price = {new BigDecimal(0)};
        final AtomicReference<Integer>[] num = new AtomicReference[]{new AtomicReference<>(0)};
        for (Product commodity : commodities) {
            CommodityResponse commodityResponse = BeanUtil.copyProperties(commodity, CommodityResponse.class);
            int amount = commodity.getStock();
            boolean status = commodity.isStatus();
            if (!status) {
                //下架
                commodityResponse.setShowStatus(CommodityStatusEnum.OFF.getValue());
                commodityResponse.setCnt(0);
                commodityResponse.setPrice(new BigDecimal("0.00"));
                commodityResponses.add(commodityResponse);
                continue;
            } else if (amount < 1) {
                //售罄
                commodityResponse.setShowStatus(3);
                commodityResponse.setCnt(0);
                commodityResponse.setPrice(new BigDecimal("0.00"));
                commodityResponses.add(commodityResponse);
                continue;
            }
            commodityRequests.forEach(commodityRequest -> {
                if (commodity.getId().equals(commodityRequest.getId())) {
                    Integer cnt = commodityRequest.getCnt();
                    if (amount < cnt) {
                        //库存不足
                        cnt = amount;
                    }
                    commodityResponse.setCnt(cnt);
                    Integer finalCnt = cnt;
                    num[0].updateAndGet(v -> v + finalCnt);
                    price[0] = price[0].add(commodity.getSalePrice().multiply(new BigDecimal(finalCnt)));
                    commodityResponse.setShowStatus(4);
                }
            });
            commodityResponses.add(commodityResponse);
        }
        checkOrderResponse.setPrice(price[0].toString());
        checkOrderResponse.setNum(num[0].get());
        checkOrderResponse.setCommodityResponses(commodityResponses);
        if (new BigDecimal(checkOrderResponse.getPrice()).compareTo(new BigDecimal(0)) == 0) {
            checkOrderResponse.setTotalPrice(new BigDecimal("0.00").toString());
            checkOrderResponse.setExpressFee(new BigDecimal("0.00").toString());
        } else {
            checkOrderResponse.setTotalPrice(originalExpressFee.add(price[0]).setScale(2, RoundingMode.HALF_UP).toString());
        }

        return checkOrderResponse;
    }

    @Override
    public PayPageInfo getPayPageInfo() {
        PayPageInfo payPageInfo = new PayPageInfo();
        String userId = JwtUtil.getUserId();
        UserExtra userExtra = userExtraMapper.selByUserId(userId);
        if (userExtra != null) {
            payPageInfo.setReceiveName(userExtra.getReceiveName());
            String receivePhone = userExtra.getReceivePhone();
            payPageInfo.setReceivePhone(receivePhone);
            if (!ObjectUtils.isEmpty(receivePhone)) {
                if (receivePhone.length() == 11) {
                    receivePhone = PhoneEncoderUtil.desensitization(receivePhone);
                }
                payPageInfo.setNewReceivePhone(receivePhone);
            }

        }
        return payPageInfo;
    }

    @Override
    public OrderDetailResp getOrderDetail(String orderSn) {
        OrderPO orderPO = orderInfoMapper.selByOrderSn(orderSn);
        if (orderPO == null) {
            throw new BusinessException("订单不存在");
        }
        String orderNo = orderPO.getOrderNo();

        List<OrderCommodity> orderCommodities = orderCommodityMapper.selectByOrderSn(orderNo);
        OrderDetailResp orderDetailResp = BeanUtil.copyProperties(orderPO, OrderDetailResp.class);
        String payPhone = orderDetailResp.getPayPhone();
        if (!ObjectUtils.isEmpty(payPhone) && payPhone.length() == 11) {
            orderDetailResp.setPayPhone(PhoneEncoderUtil.desensitization(payPhone));
        }
        String placementPointId = orderPO.getPlacementPointId();
        PlacementPoint placementPoint = customDeliveryPointMapper.selectById(placementPointId);
        if (!ObjectUtils.isEmpty(placementPoint)) {
            orderDetailResp.setDeliveryPointName(placementPoint.getName());
            Integer expressDuration = placementPoint.getExpressDuration();
            if (expressDuration != null) {        // 获取当前日期时间
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(orderPO.getCreatedAt());
                calendar.add(Calendar.MINUTE, expressDuration);
                orderDetailResp.setEstimatedDeliveryTime(calendar.getTime());
            }

        }
        if (CollectionUtil.isNotEmpty(orderCommodities)) {
            List<OrderDetailResp.OrderCommodityResp> orderCommodityRespList = BeanUtil.copyProperties(orderCommodities, OrderDetailResp.OrderCommodityResp.class);
            orderDetailResp.setOrderCommodities(orderCommodityRespList);
            Integer totalCnt = orderCommodityRespList.stream().map(OrderDetailResp.OrderCommodityResp::getCnt).reduce(0, Integer::sum);
            orderDetailResp.setTotalCnt(totalCnt);
        }
        return orderDetailResp;
    }


}
